home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
-
- Gnucleus - A node application for the Gnutella network
- Copyright (C) 2000 John Marshall
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For support, questions, comments, etc...
- E-Mail:
- swabby@c0re.net
-
- Address:
- 21 Cadogan Way
- Nashua, NH, USA 03062
-
- ********************************************************************************/
-
- // ViewSearch.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "Gnucleus.h"
- #include "MainFrm.h"
-
- #include "GnucleusDoc.h"
- #include "ViewTransfer.h"
- #include "ViewSearch.h"
-
- #include "IPFilter.h"
-
- #include "GnuTransfer.h"
- #include "GnuHash.h"
- #include "GnuSock.h"
- #include "GnuControl.h"
-
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewSearch
-
- IMPLEMENT_DYNCREATE(CViewSearch, CFormView)
-
- CViewSearch::CViewSearch()
- : CFormView(CViewSearch::IDD)
- {
- //{{AFX_DATA_INIT(CViewSearch)
- //}}AFX_DATA_INIT
-
- BytesPerSec = 0;
-
- row = 0;
- matches = 0;
- }
-
- CViewSearch::~CViewSearch()
- {
- }
-
- void CViewSearch::DoDataExchange(CDataExchange* pDX)
- {
- CFormView::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CViewSearch)
- DDX_Control(pDX, IDC_BUTTON_DOWNLOAD, m_btnDownload);
- DDX_Control(pDX, IDC_STATIC_MATCHES, m_stcMatches);
- DDX_Control(pDX, IDC_STATIC_SUBSEARCH, m_stcSubsearch);
- DDX_Control(pDX, IDC_STATIC_EXCLUDE, m_stcExclude);
- DDX_Control(pDX, IDC_LIST_RESULTS, m_lstResults);
- DDX_Control(pDX, IDC_EDIT_SUBSEARCH, m_eSubsearch);
- DDX_Control(pDX, IDC_EDIT_EXCLUDE, m_eExclude);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CViewSearch, CFormView)
- //{{AFX_MSG_MAP(CViewSearch)
- ON_WM_SIZE()
- ON_NOTIFY(NM_DBLCLK, IDC_LIST_RESULTS, OnDblclkListResults)
- ON_BN_CLICKED(IDC_BUTTON_DOWNLOAD, OnButtonDownload)
- ON_NOTIFY(NM_CLICK, IDC_LIST_RESULTS, OnClickListResults)
- ON_NOTIFY(NM_RCLICK, IDC_LIST_RESULTS, OnRightClickListResults)
- ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST_RESULTS, OnItemclickListResults)
- ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_RESULTS, OnColumnclickListResults)
- ON_EN_CHANGE(IDC_EDIT_SUBSEARCH, OnChangeSubsearch)
- ON_EN_CHANGE(IDC_EDIT_EXCLUDE, OnChangeExclude)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewSearch diagnostics
-
- #ifdef _DEBUG
- void CViewSearch::AssertValid() const
- {
- CFormView::AssertValid();
- }
-
- void CViewSearch::Dump(CDumpContext& dc) const
- {
- CFormView::Dump(dc);
- }
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewSearch message handlers
-
- void CViewSearch::OnInitialUpdate()
- // Initializes all the dialog controls on the local view
- {
- CFormView::OnInitialUpdate();
-
- Doc = (CGnucleusDoc *) GetDocument();
- Comm = Doc->GnuComm;
-
- NoScroll = 0;
-
- // Resize the window, set up the list box
- int offSet;
-
- if(m_lstResults.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- CRect rect;
- m_lstResults.GetWindowRect(&rect);
-
- m_lstResults.InsertColumn(0, "Name", LVCFMT_LEFT,
- (rect.Width() - offSet) * 5/12, 0);
- m_lstResults.InsertColumn(1, "Bytes", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 2/12, 1);
- m_lstResults.InsertColumn(2, "Type", LVCFMT_LEFT,
- (rect.Width() - offSet) * 2/12, 1);
- m_lstResults.InsertColumn(3, "Node", LVCFMT_CENTER,
- (rect.Width() - offSet) * 2/12, 0);
- m_lstResults.InsertColumn(4, "Speed", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 1/12, 0);
-
- m_lstResults.SetExtendedStyle(LVS_EX_FULLROWSELECT);
-
- GetParentFrame()->GetClientRect(&rect);
- OnSize(SIZE_RESTORED, rect.right - 4, rect.bottom - 4);
-
- // Create and set the image list to store file icons
- m_lstResults.SetImageList(GetSharedImageList(), LVSIL_SMALL);
-
- // disable plain text sort with search items.
- m_lstResults.EnableGenericSort(FALSE);
-
- // Disable button
- m_btnDownload.EnableWindow(FALSE);
-
- // Get search value from title
- CString Title;
-
- GetParentFrame()->GetWindowText(Title);
- length = Title.GetLength() - 16;
- keyword = Title.Mid(15, length);
-
- // Send a search query out for the keyword
- CString strSpeed;
- CComboBox *cbSpeed = (CComboBox *) ( (CMainFrame *) AfxGetApp()->m_pMainWnd )->GetDialogBar()->GetDlgItem(IDC_COMBO_SPEED);
- cbSpeed->GetWindowText(strSpeed);
-
-
- BytesPerSec = GetSpeedinBytes(strSpeed);
-
- Send_Query();
- }
-
- WORD CViewSearch::GetSpeedinBytes(CString Speed)
- // Speeds are in *bytes*/second
- {
- if(Speed == "")
- return 0;
- if(Speed == "14.4 Modem")
- return 14;
- if(Speed == "28.8 Modem")
- return 29;
- if(Speed == "56K Modem")
- return 53;
- if(Speed == "ISDN-56K")
- return 56;
- if(Speed == "ISDN-128K")
- return 128;
- if(Speed == "Cable")
- return 384;
- if(Speed == "DSL")
- return 768;
- if(Speed == "T1")
- return 1500;
- if(Speed == "T3 (or Greater)")
- return 45000;
-
- return (WORD) atof(Speed);
- }
-
-
- void CViewSearch::Send_Query()
- // Build a query packet
- {
- GUID Guid = GUID_NULL;
- ::CoCreateGuid(&Guid);
- if (Guid == GUID_NULL)
- {
- AfxMessageBox("Failed to create a GUID to send.");
- return;
- }
-
- myGuid = Guid;
-
- BYTE QueryByte[23 + 255];
- packet_Query Query;
- byte *pQuery = (byte *) &Query;
-
- Query.Header.Guid = Guid;
- Query.Header.Function = 0x80;
- Query.Header.Hops = 0;
- Query.Header.TTL = 7;
- Query.Header.Payload = flipX( makeX(length + 3) );
- Query.Speed = BytesPerSec;
-
- for(int i = 0; i < 25; i++)
- QueryByte[i] = pQuery[i];
-
- // Add Search
- for(i = 0; i < keyword.GetLength(); i++)
- QueryByte[25 + i] = keyword.GetAt(i);
-
- QueryByte[25 + length] = NULL;
-
- // Insert GUID and broadcast the query
- // Comm->m_cache[Guid] = NULL;
- // Comm->HashTable.Insert(&Guid, NULL);
- Comm->SendTable.Insert(&Guid, NULL);
- Comm->Broadcast_Query((packet_Query *) QueryByte, 26 + length, NULL);
- }
-
- // move into position one of the controls at the bottom of the search window
- void CViewSearch::AdjustBottomControl(CWnd *cntl, int bot)
- {
- CRect r, par;
- cntl->GetWindowRect(&r);
- ScreenToClient(&r);
- const int hoff = 2, height = 32;
- cntl->MoveWindow(r.left, (bot - hoff - height) + (height - r.Height()) / 2, r.Width(), r.Height());
- }
-
- void CViewSearch::OnSize(UINT nType, int cx, int cy)
- // Adjusts dialog controls when window in resized
- {
- // Make sure dialog controls exist
- if(m_lstResults.m_hWnd != NULL)
- {
- int top, left, btnLeft, btnRight, btnBottom;
- // int btn2Left, btn2Right; // DW - not used yet?
-
- RECT wndRect,
- lstRect,
- btnRect;
- // btnRect2; // DW BTW, btnRect2 is not used for anything yet
-
- GetWindowRect(&wndRect);
- m_lstResults.GetWindowRect(&lstRect);
- m_btnDownload.GetWindowRect(&btnRect);
-
- top = lstRect.top - wndRect.top - 2;
- left = lstRect.left - wndRect.left - 2;
-
- btnLeft = btnRect.left - wndRect.left - 2;
- btnRight = btnRect.right - btnRect.left;
- btnBottom = btnRect.bottom - btnRect.top;
-
- // btn2Left = btnRight + 8; // DW So, these are not valid yet
- // btn2Right = btnRect2.right - btnRect2.left;
-
- m_lstResults.MoveWindow(left, top, cx - left - 7, cy - top - btnBottom - 17);
- m_btnDownload.MoveWindow(btnLeft, cy - 8 - btnBottom, btnRight, btnBottom);
-
- AdjustBottomControl(&m_eSubsearch, cy);
- AdjustBottomControl(&m_stcSubsearch, cy);
- AdjustBottomControl(&m_stcExclude, cy);
- AdjustBottomControl(&m_eExclude, cy);
-
- // Resize list box
- int offSet;
-
- if(m_lstResults.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- CRect rect;
- m_lstResults.GetWindowRect(&rect);
-
- m_lstResults.SetColumnWidth(0, (rect.Width() - offSet) * 5/12);
- m_lstResults.SetColumnWidth(1, (rect.Width() - offSet) * 2/12);
- m_lstResults.SetColumnWidth(2, (rect.Width() - offSet) * 2/12);
- m_lstResults.SetColumnWidth(3, (rect.Width() - offSet) * 2/12);
- m_lstResults.SetColumnWidth(4, (rect.Width() - offSet) * 1/12);
- }
-
- CFormView::OnSize(nType, cx, cy);
-
- }
-
- void CViewSearch::UpdateResults(byte *Result)
- {
- if( ((packet_Header *) Result)->Guid != myGuid)
- return;
-
- DWORD length = makeD( flipX( ((packet_Header *) Result)->Payload)) + 23;
- CString Node = IPtoStr( ((packet_QueryReply *) Result)->Host );
- CString Port = WrdtoStr( ((packet_QueryReply *) Result)->Port );
- CString Speed = DWrdtoStr( makeD( flipX( ((packet_QueryReply *) Result)->Speed)) );
- CString File;
- CString Size;
- CString FileType;
-
- byte hitsLeft = ((packet_QueryReply *) Result)->TotalHits;
- DWORD nextPos = 34;
- QueryItem Item;
-
- GUID guid;
- ::memset (&guid, 0, sizeof (guid));
- if (hitsLeft > 0)
- {
- // Extract the GUID from the end of the packet for push requests
- DWORD guidStart = length - 16;
-
- guid = * (GUID*) (Result + guidStart);
- }
-
- while(nextPos < length - 16 && hitsLeft > 0)
- {
- packet_QueryReplySet* ReplySet = (packet_QueryReplySet *) &Result[nextPos];
-
- Size = DWrdtoStr( makeD( flipX( ReplySet->Size)) );
-
- nextPos += 8;
-
- while( !(Result[nextPos] == NULL && Result[nextPos + 1] == NULL))
- if(nextPos > length - 16)
- return;
- else
- File += Result[nextPos++];
-
- if(Size == "0" || File == "")
- return;
-
- if( InspectFile(File) )
- {
- FileType = GetIconDesc(File);
-
- // Add to listbox
- // check if it passes subsearch
-
- CString lowtxt = File;
- lowtxt.MakeLower();
- bool fnd; // represents whether passes subsearch and sub-excludes
- if (subsearchText.GetLength() == 0)
- fnd = true; // no subsearch
- else
- fnd = lowtxt.Find(subsearchText) >= 0;
- Item.subsearchMatch = fnd;
-
- // try excluding
- Item.excluded = ExcludeTest(excludeText, lowtxt);
-
- fnd = fnd && !Item.excluded;
-
- if (fnd)
- {
- m_lstResults.InsertItem(row, "" );
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Name" ), File);
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Bytes" ), CommaIze(Size));
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Type" ), FileType);
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Node" ), Node);
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Speed" ), Speed + " Kbs");
- Item.Handle = row; // invalid, BTW
- }
-
- // Add to search results linked list
-
- Item.Port = ((packet_QueryReply *) Result)->Port;
- Item.Host = ((packet_QueryReply *) Result)->Host;
-
- Item.Speed = makeD( flipX(((packet_QueryReply *) Result)->Speed));
- Item.Index = makeD( flipX(ReplySet->Index));
- Item.Size = makeD( flipX(ReplySet->Size));
-
- // Remove directory information from the file name
- int slash = File.ReverseFind('/');
- File = File.Mid(slash + 1);
-
- Item.FileName = File;
- Item.FileType = FileType; // Ineffiecent, replace with list in future
-
- Item.Guid = guid;
-
- // Add the icon
- Item.IconIndex = GetIconIndexFromName(File);
- Replies.push_back (Item);
-
- if(fnd && Item.IconIndex != -1)
- {
- m_lstResults.SetItem(row, 0, LVIF_IMAGE, NULL, Item.IconIndex, m_lstResults.GetColumnNumber( "Name" ), 0, NULL);
- }
-
- // Check to see if the scroll bar needs to be added
- if( fnd && !NoScroll && m_lstResults.GetScrollLimit(SB_VERT))
- {
- CRect rect;
- GetParentFrame()->GetClientRect(&rect);
- OnSize(SIZE_RESTORED, rect.right - 4, rect.bottom - 4);
-
- NoScroll = 1;
- }
-
- if (fnd)
- row++;
- matches++;
- }
-
- File = "";
- Size = "";
-
- nextPos += 2;
- hitsLeft--;
- }
-
- AssignHeaderText();
- }
-
- bool CViewSearch::InspectFile(CString File)
- {
- bool Pass = 0;
- File.MakeLower();
-
- std::vector<BlockedSearch>::iterator it;
-
- for( it = Doc->SearchFilter.begin(); it != Doc->SearchFilter.end(); it++)
- {
- if( (*it).Permis == 'A' )
- if( SearchMatch( (*it).Name, File) )
- Pass = 1;
-
- if( (*it).Permis == 'D' )
- if( SearchMatch( (*it).Name, File) )
- return 0;
- }
-
- return Pass;
- }
-
- void CViewSearch::OnItemclickListResults(NMHDR* pNMHDR, LRESULT* pResult)
- {
- HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;
-
- if(phdn->iButton == 0)
- {
- AfxMessageBox(m_lstResults.GetItemText(0, phdn->iItem));
- }
-
-
- *pResult = 0;
- }
-
- void CViewSearch::OnClickListResults(NMHDR* pNMHDR, LRESULT* pResult)
- {
- m_btnDownload.EnableWindow(m_lstResults.GetFirstSelectedItemPosition() != NULL);
- *pResult = 0;
- }
-
- // pop up a popup menu, which right now lets one filter out a user
- void CViewSearch::OnRightClickListResults(NMHDR* pNMHDR, LRESULT* pResult)
- {
- LPNMITEMACTIVATE Control = (LPNMITEMACTIVATE) pNMHDR;
-
- int nItem = m_lstResults.HitTest(Control->ptAction);
- if (nItem < 0 || nItem >= matches)
- return;
-
- CMenu menu;
- VERIFY(menu.LoadMenu(IDR_SRCH_RCLICK));
- CMenu *pmenuPopup = menu.GetSubMenu(0);
- ASSERT(pmenuPopup != NULL);
-
- // Display and track the popup menu
- CPoint pos;
- GetCursorPos(&pos);
-
- int res = pmenuPopup->TrackPopupMenu( (TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD),
- pos.x, pos.y, this);
- if (res == ID_FILTER) {
- // they want to filter this user
- // find out which result they clicked on
- QueryItem& qry = FindQueryItemFromListIndex(nItem);
- // now add the filter to our list
- CIPFilter::AddFilter(CIPFilter::CIPAddress(qry.Host.a,qry.Host.b,qry.Host.c,qry.Host.d),
- CIPFilter::CFilterItem::EFilterAction(CIPFilter::CFilterItem::eFilterDeny),
- true); // true here necessary
- // remove all the results from this loser that are currently displayed
- IP host(qry.Host);
- std::list<QueryItem>::iterator it;
- for (it = Replies.begin(); it != Replies.end(); )
- {
- if (it->Host.S_addr == host.S_addr)
- {
- it = Replies.erase(it);
- continue;
- }
- it++;
- }
- // redraw
- ListFromReplies();
- AssignHeaderText();
- }
- *pResult = 0;
- }
-
- void CViewSearch::OnDblclkListResults(NMHDR* pNMHDR, LRESULT* pResult)
- {
- LPNMITEMACTIVATE Control = (LPNMITEMACTIVATE) pNMHDR;
-
- int nItem = m_lstResults.HitTest(Control->ptAction);
- CString Title;
-
- if(nItem != -1)
- StartDownload(nItem);
- *pResult = 0;
- }
-
- void CViewSearch::OnButtonDownload()
- {
- int nItem;
- POSITION pos = m_lstResults.GetFirstSelectedItemPosition();
-
- while(pos != NULL)
- {
- nItem = m_lstResults.GetNextSelectedItem(pos);
- StartDownload(nItem);
- }
- }
-
- void CViewSearch::OnColumnclickListResults(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
-
- if (QueryItem::SortBy == pNMListView->iSubItem)
- {
- QueryItem::Reverse = !QueryItem::Reverse;
- }
- else
- {
- QueryItem::SortBy = pNMListView->iSubItem;
- QueryItem::Reverse = 0;
- }
-
- Replies.sort ();
-
- ListFromReplies();
-
- *pResult = 0;
- }
-
-
- void CViewSearch::OnChangeSubsearch()
- {
- CString s;
- m_eSubsearch.GetWindowText(s);
- s.MakeLower();
- subsearchText = s;
-
- // see which replies match string
- // keep track to see if we've made changes -- whether to reform list or not
- bool madeAChange = false;
- std::list<QueryItem>::iterator it;
- for (it = Replies.begin(); it != Replies.end(); it++)
- {
- if (s.GetLength() == 0)
- {
- if (!it->subsearchMatch)
- {
- madeAChange = true;
- it->subsearchMatch = true;
- }
- continue;
- }
- CString lo = it->FileName;
- lo.MakeLower();
- bool oldMatch = it->subsearchMatch;
- bool fnd = SearchMatch("*" + s + "*", lo);
- it->subsearchMatch = fnd;
- if (it->subsearchMatch != oldMatch)
- madeAChange = true;
- }
-
- if (madeAChange)
- {
- Replies.sort();
- ListFromReplies();
- AssignHeaderText();
- }
- }
-
- // Test name against comma delimited excludes, return true if one matches
- bool CViewSearch::ExcludeTest(CString exclude, CString name)
- {
- if (exclude.GetLength() == 0)
- return false;
-
- name.MakeLower();
- exclude.MakeLower();
- // parse exclude out
-
- CString strSub;
- int iToken = 0;
-
- while(AfxExtractSubString(strSub, exclude, iToken, ','))
- {
- iToken++;
- if(SearchMatch("*" + strSub + "*", name))
- {
- return true;
- }
- }
-
- return false;
- }
-
- void CViewSearch::OnChangeExclude()
- {
- CString s;
- m_eExclude.GetWindowText(s);
- s.MakeLower();
- excludeText = s;
-
- // see which replies match exclude string -- they're invalid
- // keep track to see if we've made changes -- whether to reform list or not
- bool madeAChange = false;
- std::list<QueryItem>::iterator it;
- for (it = Replies.begin(); it != Replies.end(); it++)
- {
- if (s.GetLength() == 0)
- {
- if (it->excluded)
- {
- madeAChange = true;
- it->excluded = false;
- }
- continue;
- }
- bool match = ExcludeTest(s, it->FileName);
- bool oldMatch = it->excluded;
- it->excluded = match;
- if (match != oldMatch)
- madeAChange = true;
- }
-
- if (madeAChange)
- {
- Replies.sort();
- ListFromReplies();
- AssignHeaderText();
- }
- }
-
- /*
- take our reply list and create the elements of the listcontrol from it
- also count rows, as we might have just done some subsearch
- */
- void CViewSearch::ListFromReplies()
- {
-
- m_lstResults.SetRedraw (FALSE);
- m_lstResults.DeleteAllItems();
-
- std::list<QueryItem>::iterator it;
-
- row = 0;
-
- for (it = Replies.begin(); it != Replies.end(); it++)
- {
- if (!it->subsearchMatch || it->excluded)
- continue;
-
- // Add to listbox
- m_lstResults.InsertItem(row, "");
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Name" ), (*it).FileName);
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Bytes" ), CommaIze(DWrdtoStr((*it).Size)));
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Type" ), (*it).FileType);
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Node" ), IPtoStr((*it).Host));
- m_lstResults.SetItemText(row, m_lstResults.GetColumnNumber( "Speed" ), DWrdtoStr((*it).Speed) + " Kbs");
-
- if ((*it).IconIndex != -1)
- {
- m_lstResults.SetItem(row, 0, LVIF_IMAGE, NULL, (*it).IconIndex, m_lstResults.GetColumnNumber( "Name" ), 0, NULL);
- }
-
- row++;
- }
-
- m_lstResults.SetRedraw();
- }
-
- // set the header text -- how many matches so far
- void CViewSearch::AssignHeaderText()
- {
- CString Title = WrdtoStr(matches);
- Title += " Matches";
- // maybe there's a subsearch -- if so, add text
- if (matches != row)
- Title += " (" + WrdtoStr(row) + " shown)";
- m_stcMatches.SetWindowText(Title);
- }
-
- QueryItem& CViewSearch::FindQueryItemFromListIndex(int nItem)
- {
- ASSERT (nItem >= 0);
- ASSERT (nItem < Replies.size ());
-
- std::list <QueryItem>::iterator it;
-
- it = Replies.begin();
- // find the associated reply
- while ( (it != Replies.end()) && (!it->subsearchMatch || it->excluded) )
- it++;
- for (int loop = 0; loop < nItem && (it != Replies.end()); ++loop)
- {
- do {
- it++;
- } while ( (it != Replies.end()) && (!it->subsearchMatch || it->excluded) );
- }
-
- ASSERT (it != Replies.end ());
-
- return *it;
- }
-
- void CViewSearch::StartDownload(int nItem)
- {
-
- ((CGnucleusApp *) AfxGetApp())->TransferFrame->ShowWindow(SW_SHOW);
- ((CGnucleusApp *) AfxGetApp())->TransferFrame->BringWindowToTop();
-
- QueryItem& qry = FindQueryItemFromListIndex(nItem);
-
- int b_is_dest_private_ip = CIPFilter::IsPrivateIP( qry.Host, StrtoIP(Comm->localHost) );
-
- if( b_is_dest_private_ip == 0x2)
- Comm->NewPushRequest(qry); // the remote download is not on the local subnet, push is the only way
- else if( b_is_dest_private_ip == 0x4)
- return; // we are on a different private IP address space. There is no way of download.
- // TODO: generate an error message
- else
- // the destination is either on an open IP space, or it might be on our local address space, if not a push is generated.
- ((CViewTransfer *) ((CGnucleusApp *) AfxGetApp())->TransferFrame->GetActiveView())->NewDownload(qry);
-
- }
-